package mysql.cs.handshake;

import common.MysqlCanalC;
import common.Util.ByteUtil;
import mysql.MysqlPacket;
import mysql.MysqlPacketHeader;

import java.io.IOException;

/**
 * @ClassName HandshakeV10
 * @Description TODO
 * @Author fengk
 * @Date 2018/8/27
 *
 * 1              [0a] protocol version
 * string[NUL]    server version
 * 4              connection id
 * string[8]      auth-plugin-data-part-1
 * 1              [00] filler
 * 2              capability flags (lower 2 bytes)
 *   if more data in the packet:
 * 1              character set
 * 2              status flags
 * 2              capability flags (upper 2 bytes)
 *   if capabilities & CLIENT_PLUGIN_AUTH {
 * 1              length of auth-plugin-data
 *   } else {
 * 1              [00]
 *   }
 * string[10]     reserved (all [00])
 *   if capabilities & CLIENT_SECURE_CONNECTION {
 * string[$len]   auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8))
 *   if capabilities & CLIENT_PLUGIN_AUTH {
 * string[NUL]    auth-plugin name
 *   }
 */

public class HandshakeV10 extends MysqlPacket {
    public byte   protocolVersion = MysqlCanalC.DEFAULT_PROTOCOL_VERSION;
    public String serverVersion;
    public long   connectId;
    public byte[] authPluginData1;
    public int    capabilities;
    public byte   serverCharsetNumber;
    public int    serverStatus;
    public long authPluginData2Len;
    public byte[] authPluginData2;
    public byte[] restOfScrambleBuff;

    public HandshakeV10(MysqlPacketHeader mysqlPacketHeader) {
        super(mysqlPacketHeader);
    }

    public HandshakeV10() {
    }
    public void encode(byte[] data){
        int index=0;
        // protocol version
        protocolVersion=data[index];
        index++;
        //server version
        byte[] serverVersionBytes= ByteUtil.readNullTerminatedBytes(data,index);
        index+=(serverVersionBytes.length+1/** 0x00*/);
        serverVersion=new String(serverVersionBytes);
        //connect id
        connectId=ByteUtil.readUnsignedIntLittleEndian(data,index);
        index+=4;
        //authPluginData
        authPluginData1=ByteUtil.readFixedLengthBytes(data,index,8);
        index+=8;
        index+=1; //always 0x00
        // capabilities
        capabilities=ByteUtil.readUnsignedShortLittleEndian(data,index);
        index+=2;
        serverCharsetNumber=data[index];
        index++;
        //server status
        serverStatus=ByteUtil.readUnsignedShortLittleEndian(data,index);
        index+=2;
        //capabilities (upper 2 bytes)
        capabilities=capabilities+(ByteUtil.readUnsignedShortLittleEndian(data,index)<<16);
        index+=2;
        if((capabilities&MysqlCanalC.CLIENT_PLUGIN_AUTH)==0){
            index+=1;
        }else {
            try {
                authPluginData2Len=ByteUtil.readLengthCodedBinary(data,index);
                index+=ByteUtil.readLengthCodedBinaryLen(data,index);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 0x00
        index+=10;
        if((capabilities&MysqlCanalC.CLIENT_SECURE_CONNECTION)!=0){
            long readFixDataLen=authPluginData2Len-8>13?authPluginData2Len-8:13;
            if(readFixDataLen<((long)1<<32)){
                //最后是0x00所以减1
                //是否减1跟版本有关
                authPluginData2=ByteUtil.readFixedLengthBytes(data,index,(int)readFixDataLen-1);
            }else {
                //不可能
            }

            index+=readFixDataLen;
        }
        restOfScrambleBuff=ByteUtil.readEOFTerminatedBytes(data,index);
    }

    /**
     * error
     * @return
     * @throws IOException
     */
    public byte[] decode() throws IOException{
        return null;
    }
}

